// 枚举
enum Player {
  X = 'x',
  O = 'o'
}

// 获取所有单元格列表 伪数组
let cells = document.querySelectorAll('.cell');
// 游戏面板
let gameBord = document.querySelector('#bord')
// 获胜信息
let message = document.querySelector('#message') as HTMLDivElement
// 获胜者
let winner = document.querySelector('#winner') as HTMLParagraphElement
// 存储玩家变量
// let currentPlayer: player = player.X
let currentPlayer: Player
// 判赢数组
let winsArr = [
  [0, 1, 2], [3, 4, 5], [6, 7, 8], //横
  [0, 3, 6], [1, 4, 7], [2, 5, 8], //竖
  [0, 4, 8], [2, 4, 6]             //斜
]
// 记录下棋步数
let steps: number
// 重新开始按钮
let restart = document.querySelector('#restart') as HTMLButtonElement

// 重新开始
restart.addEventListener('click', startGame)

// 调用该函数初始化游戏数据，开始游戏
startGame()
function startGame() {
  // console.log('click');
  // 重置游戏数据
  // 隐藏获胜面板
  message.style.display = 'none'
  // 重置下棋次数
  steps = 0
  // 重置默认玩家
  currentPlayer = Player.X
  // 重置下棋提示为x
  gameBord?.classList.remove(Player.X, Player.O)
  gameBord?.classList.add(Player.X)

  cells.forEach(function (item) {
    let cell = item as HTMLDivElement
    // 清空棋盘
    cell.classList.remove(Player.X, Player.O)
    // 移除单元格点击事件
    cell.removeEventListener('click', clickCell)
    // 重新给单元格绑定点击事件
    cell.addEventListener('click', clickCell, { once: true })
  })
}

/* // 遍历列表添加点击事件
// 防止单元格重复点击 once：ture
cells.forEach(function (item) {
  let cell = item as HTMLDivElement
  cell.addEventListener('click', clickCell, { once: true })
}) */

// 棋盘中单元格click事件处理程序
function clickCell(event: MouseEvent) {
  // console.log('click', event.target);
  let target = event.target as HTMLDivElement
  target.classList.add(currentPlayer)
  // 点击后添加类名步数加一
  steps ++

  // 调用判赢函数 先判赢再判断是否平局
  let isWin = checkWin(currentPlayer)
  if (isWin) {
    // console.log('win', currentPlayer);
    message.style.display = 'block'
    winner.innerText = currentPlayer + ' 赢了!'
    // 玩家获胜 终止后续操作
    return
  }

  // 判断平局 步数（steps）等于9则平局 游戏结束 直接return
  if (steps === 9) {
    message.style.display = 'block'
    winner.innerText = '平局'
    // 终止后续操作
    return
  }

  // 根据当前玩家，得到下一个玩家
  currentPlayer = currentPlayer === Player.X ? Player.O : Player.X
  gameBord?.classList.remove(Player.X, Player.O)
  gameBord?.classList.add(currentPlayer)
}

// 封装判赢函数
function checkWin(player: Player) {
  /* let isWin = winsArr.some(function (item) {
    // console.log(item);
    // 拿到每种获胜情况的三个索引
    let cellIndex1 = item[0]
    let cellIndex2 = item[1]
    let cellIndex3 = item[2]
    // console.log(cellIndex1,cellIndex2,cellIndex3);

    // 获取对应的单元格元素
    let cell1 = cells[cellIndex1]
    let cell2 = cells[cellIndex2]
    let cell3 = cells[cellIndex3]
    // console.log(cell1,cell2,cell3);

    // 判断同时包含
    if (
      cell1.classList.contains(player) &&
      cell2.classList.contains(player) &&
      cell3.classList.contains(player)
    ) {
      return true
    }
    return false
  })
  return isWin */

  // 优化 去掉判赢函数中间变量
  return winsArr.some(function (item) {
    // console.log(item);
    // 拿到每种获胜情况的三个索引
    let cellIndex1 = item[0]
    let cellIndex2 = item[1]
    let cellIndex3 = item[2]
    // console.log(cellIndex1,cellIndex2,cellIndex3);

    // 判断同时包含
    if (
      // cells[cellIndex1].classList.contains(player) &&
      // cells[cellIndex2].classList.contains(player) &&
      // cells[cellIndex3].classList.contains(player)
      hasClass(cells[cellIndex1], player) &&
      hasClass(cells[cellIndex2], player) &&
      hasClass(cells[cellIndex3], player)
    ) {
      return true
    }
    return false
  })
}

// 封装 hasClass 函数:判断 DOM 元素是否包含某个类名
function hasClass(el: Element, name: string) {
  return el.classList.contains(name)
}

